#include "epicure.h"

void CardlistTopple(LPHEAD target,LPBYTE buffer,UINT at,UINT size)
{
	LPITEM curr=target;
	for(unsigned x=at;x<=at+size-1;x++)
	{
		if (curr == nullptr) throw std::exception("WTH");
		buffer[x] = curr->content->ing->index;
		curr = curr->next;
	}
}

UINT CardlistReassign(const LPBYTE input, UINT at,LPHEAD& target,INT reassignLocType=LT_NONE)
{
	CardlistClear(target);
	for(UINT x=at;;x++)
	{
		CONST BYTE bb = input[x];
		if (bb == 0xff)return x+1;

		CARD gene{&ings[input[x]],0,0,false};
		UINT index = x - at;

		switch(reassignLocType)
		{
		case LT_HAND:
			{
			gene.locY = CARD_TOP;
			gene.locX = CARD_LEFT + index * (CARD_WIDTH);
			break;
			}
		case LT_BLOCK:
			{
			gene.locX = 0;
			gene.locY = STANDPOINT_Y - BLOCK_HEIGHT-BLOCK_GAP * (index);
			break;
			}
		default:;
		}

		CardlistAdd(target, gene);
	}
}

UINT_PTR Lpofnhookproc(
	HWND Arg1,
	UINT Arg2,
	WPARAM Arg3,
	LPARAM Arg4
)
{
	return DefDlgProc(Arg1, Arg2, Arg3, Arg4);
}

void SaveGame(HWND hwnd,LPCTSTR name, LPHEAD hand, LPHEAD blocks, LPHEAD pool)
{
	TCHAR slfile[MAX_PATH]={};
	
	OPENFILENAME openf{
		sizeof(OPENFILENAME),
		hwnd,
		NULL,
		 TEXT("BINARY FILE (*.bin)\0*.bin\0\0"),
		NULL,
		NULL,
		0,
		slfile,
		MAX_PATH,
		NULL,
		NULL,
		NULL,
		NULL,
		OFN_ENABLESIZING| OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST | OFN_EXPLORER,
		0,
		0,
		TEXT("bin"),
		NULL,
		Lpofnhookproc,
		NULL
	};
	
	if(GetSaveFileName(&openf)==FALSE)return;

#define SIZE_PLAYERNAME (22*sizeof(TCHAR))
#define SIZE_BLOCKS CardlistCount(blocks)
#define SIZE_SAP1 1
#define SIZE_HAND CardlistCount(hand)
#define SIZE_SAP2 1
#define SIZE_POOL CardlistCount(pool)
#define SIZE_TOTAL (SIZE_PLAYERNAME+SIZE_BLOCKS+SIZE_SAP1+SIZE_HAND+SIZE_SAP2+SIZE_POOL)

	LPBYTE bytes=new BYTE[SIZE_TOTAL];
	lstrcpy((LPTSTR)bytes, name);
	CardlistTopple(hand, bytes, SIZE_PLAYERNAME, SIZE_HAND);
	bytes[SIZE_PLAYERNAME + SIZE_HAND] = 0xff;
	CardlistTopple(blocks, bytes, SIZE_PLAYERNAME + SIZE_HAND+1, SIZE_BLOCKS);
	bytes[SIZE_PLAYERNAME + SIZE_HAND+1+SIZE_BLOCKS] = 0xff;
	CardlistTopple(pool, bytes, SIZE_PLAYERNAME + SIZE_BLOCKS + 1+SIZE_HAND+1, SIZE_POOL);

	DeleteFile(openf.lpstrFile);
	const HANDLE target = CreateFile(openf.lpstrFile, GENERIC_WRITE, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
	DWORD written;
	WriteFile(target, bytes, SIZE_TOTAL, &written, nullptr);
	CloseHandle(target);

	delete[] bytes;
}



void LoadGame(HWND hwnd, LPTSTR name, LPHEAD& hand, LPHEAD& blocks, LPHEAD& pool)
{
	TCHAR slfile[MAX_PATH] = {};

	OPENFILENAME openf{
		sizeof(OPENFILENAME),
		hwnd,
		NULL,
		 TEXT("BINARY FILE (*.bin)\0*.bin\0\0"),
		NULL,
		NULL,
		0,
		slfile,
		MAX_PATH,
		NULL,
		NULL,
		NULL,
		NULL,
		OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST | OFN_EXPLORER,
		0,
		0,
		TEXT("bin"),
		NULL,
		Lpofnhookproc,
		NULL
	};

	if (GetOpenFileName(&openf) == FALSE)return;
	
	const HANDLE target = CreateFile(openf.lpstrFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);

	DWORD high; // <- FILESIZE CANNOT BE THAT HIGH - THIS IS ALWAYS ZERO
	DWORD low = GetFileSize(target, &high);
	LPBYTE buffer = new BYTE[low];
	
	DWORD read;
	ReadFile(target, buffer,low, &read, nullptr);
	CloseHandle(target);

	lstrcpy(name, (LPCTSTR)buffer);
	UINT curr = CardlistReassign(buffer, SIZE_PLAYERNAME, hand, LT_HAND);
	curr = CardlistReassign(buffer, curr, blocks, LT_BLOCK);
	CardlistReassign(buffer, curr, pool);

	delete[] buffer;
}